<html>
<head>
  <title>How To Generate A Random Number...</title>
</head>

<body>

<!-- BEGIN LAB DESCRIPTION -->

<font face="Arial">
<!------------------------------------------------------------------------------------>
<a name="HowToRandom">
<h2>How To Generate A Random Number...</h2>
</a>

<p>Use the following routines found in <i>random.asm</i> to initialize, set, and get
random numbers:
<p>

<table border=1>
<tr>
  <th align="left">Function</th>
  <th align="left">Parameters</th>
  <th align="left">Description</th>
</tr>
<tr>
  <td width="150"><b>initRand16</b></td>
  <td width="300">&nbsp;&nbsp;&nbsp;&nbsp;IN: r12 = random seed</td>
  <td>Initialize random # generator</td>
</tr>

<tr>
  <td><b>rand16</b></td>
  <td>OUT: r12 = random number (0-32767)</td>
  <td>Get 16-bit random #</td>
</tr>

<tr>
  <td><b>setRandSeed</b></td>
  <td>&nbsp;&nbsp;&nbsp;&nbsp;IN: r12 = random seed</td>
  <td>Set random # seed</td>
</tr>

<tr>
  <td><b>getRandSeed</b></td>
  <td>OUT: r12 = random number seed</td>
  <td>Get current random # seed</td>
</tr>
</table>

<p>A pseudorandom number generator (PRNG) is an algorithm for generating a sequence of numbers
   that approximates the properties of random numbers. The sequence is not truly random in that
   it is completely determined by an initial value, called the PRNG's state or seed.
   Although sequences that are closer to truly random can be generated using hardware
   random number generators, pseudorandom numbers are important in practice for simulations
   and are central in the practice of cryptography and procedural generation.

<p>A pseudorandom number generator can be started from an arbitrary starting state using a
   seed state. It will always produce the same sequence thereafter when initialized with
   that state. The maximum length of the sequence before it begins to repeat is determined
   by the size of the state, measured in bits.
   However, since the length of the maximum period potentially doubles with each bit of
   'state' added, it is easy to build PRNGs with periods long enough for many practical
   applications. (Wikipedia, 2010.)


<p>The following is a listing of <i>random.asm</i>:

<blockquote><pre>     .title    "random.asm"
;*******************************************************************************
;   MSP430F2274 random.asm
;
;   Description:
;
;  June 2009
;  Built with Code Composer Essentials Version: 3.1
;*******************************************************************************
        .cdecls    C,LIST,"msp430x22x4.h"

;------------------------------------------------------------------------------
;    external references
;
        .def    initRand16             ; init random # generator
        .def    rand16                 ; get 16-bit random #
        .def    setRandSeed            ; set random # seed
        .def    getRandSeed            ; get current random # seed

;------------------------------------------------------------------------------
; INITIALIZATION CONSTANTS FOR RANDOM NUMBER GENERATION
;
SEED    .set    21845                  ; Arbitrary seed value (65536/3)
MULT    .set    31821                  ; Multiplier value (last 3 Digits are even21)
INC     .set    13849                  ; 1 and 13849 have been tested


;------------------------------------------------------------------------------
        .data                          ; Data Section
;------------------------------------------------------------------------------
        .bss    RandSeed,2             ; random seed

;------------------------------------------------------------------------------
        .text                          ; Program Section
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; SUBROUTINE: INITIALIZE RANDOM NUMBER GENERATOR:
;
;    IN:        r12 = random seed
;
initRand16:
        push    r4
;       mov.w   r12,RandSeed           ; init seed
        mov.w   #20,r4

init_01:
        call    #rand16                ; get random #
        dec.w   r4
          jne   init_01
        pop     r4
        ret

;------------------------------------------------------------------------------
; SUBROUTINE: SET RANDOM SEED

setRandSeed:
        mov.w   r12,RandSeed           ; set seed
        ret


;------------------------------------------------------------------------------
; SUBROUTINE: GET RANDOM SEED

getRandSeed:
        mov.w   RandSeed,r12           ; return seed
        ret
        

;------------------------------------------------------------------------------
; SUBROUTINE: GENERATES NEXT RANDOM NUMBER
;
;    OUT:    r12 = 0-32767
;            random seed updated
;
rand16: push    r4                     ; save registers
        push    r5
        push    r6
        push    r7

        mov.w   RandSeed,r5            ; Prepare multiplication
        mov.w   #MULT,r4               ; Prepare multiplication
        call    #MPYU                  ; Call unsigned MPY (5.1.1)
        add.w   #INC,r7                ; Add INC to low word of product
        mov.w   r7,RandSeed            ; Update RandSeed
        mov.w   r7,r12                 ; return in r12
        swpb    r12

        pop     r7                     ; restore registers
        pop     r6
        pop     r5
        pop     r4
        ret                            ; Random number in Rndnum


;------------------------------------------------------------------------------
; Integer Subroutines Definitions: Software Multiply
; See SLAA024 - MSP430 Family Mixed-Signal Microcontroller Application Reports
;
; UNSIGNED MULTIPLY: r4 x r5 -> r6|r7
;
MPYU:   clr.w   r7                     ; 0 -> LSBs RESULT
        clr.w   r6                     ; 0 -> MSBs RESULT

; UNSIGNED MULTIPLY AND ACCUMULATE: (r4 x r5) + r6|r7 -> r6|r7
;
MACU:   push    r8
        clr.w   r8                     ; MSBs MULTIPLIER

L$01:   bit.w   #1,r4                  ; TEST ACTUAL BIT 5-4
          jz    L$02                   ; IF 0: DO NOTHING
        add.w   r5,r7                  ; IF 1: ADD MULTIPLIER TO RESULT
        addc.w  r8,r6

L$02:   rla.w   r5                     ; MULTIPLIER x 2
        rlc.w   r8
        rrc.w   r4                     ; NEXT BIT TO TEST
          jnz   L$01                   ; IF BIT IN CARRY: FINISHED

L$03:   pop     r8
        ret

        .end</pre></blockquote>
<!-- END LAB DESCRIPTION -->

</body>
</html>
